<!DOCTYPE html>
<html lang="zh-CN">
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="utf-8">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
  
  <title itemprop="name">C++面向对象高级编程 -- 侯捷 | lichen</title>
  
    <link rel="shortcut icon" href="/images/favicon.ico">
  
  <meta http-equiv="x-dns-prefetch-control" content="on">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+SerifMerriweather|Merriweather+Sans|Source+Code+Pro|Ubuntu:400,700|Noto+Serif+SC" media="all">
  <link rel="dns-prefetch" href="//cdn.jsdelivr.net">
  <link rel="stylesheet" id="saukra_css-css" href="/css/style.css" type="text/css" media="all">
  <link rel="stylesheet" href="/css/lib.min.css" media="all">
  <link rel="stylesheet" href="/css/font.css" media="all">
  <link rel="stylesheet" href="/css/insight.css" media="all">
  <link rel="stylesheet" href="/css/jquery.fancybox.min.css" media="all">
  <link rel="stylesheet" href="/css/zoom.css" media="all">
  <link rel="stylesheet" type="text/css" href="/css/sharejs.css">
<!--   <link rel="stylesheet" id="saukra_css-css" href="https://2heng.xin/wp-content/cache/autoptimize/css/autoptimize_ad42a61f4c7d4bdd9f91afcff6b5dda5.css
" type="text/css" media="all"> -->
  <script>
  /*Initial Variables*/
  var mashiro_option = new Object();
  var mashiro_global = new Object();
  mashiro_option.NProgressON = true;
  /* 
   * 邮箱信息之类的东西可以填在这里，这些js变量基本都作用于sakura-app.js
   * 这样的设置仅是为了方便在基于PHP开发的主题中设置js变量，既然移植到了Node上，我想或许可以精简这一逻辑吧
   */
  mashiro_option.email_domain = "";
  mashiro_option.email_name = "";
  mashiro_option.cookie_version_control = "";
  mashiro_option.qzone_autocomplete = false;
  mashiro_option.site_name = "LCsite";
  mashiro_option.author_name = "site";
  mashiro_option.site_url = "https://lichen312.gitee.io/blog/";
  mashiro_option.v_appId = "GyC3NzMvd0hT9Yyd2hYIC0MN-gzGzoHsz";
  mashiro_option.v_appKey = "mgOpfzbkHYqU92CV4IDlAUHQ";
  mashiro_option.mathjax = "0";
  mashiro_option.qq_api_url = "https://api.mashiro.top/qqinfo/"; 
  mashiro_option.qq_avatar_api_url = "https://api.mashiro.top/qqinfo/";

  // mashiro_option.jsdelivr_css_src = "https://cdn.jsdelivr.net/gh/moezx/cdn@3.4.5/css/lib.min.css";
  // mashiro_option.float_player_on = true;

  /*End of Initial Variables*/
  </script>
  <script type="text/javascript">
  var bg = "https://gitee.com/lichen312/picbed/raw/master/image/flower.jpg,https://gitee.com/lichen312/picbed/raw/master/image/sakura.png".split(",");
  var bgindex = Math.floor(Math.random()*bg.length);
  if (!!window.ActiveXObject || "ActiveXObject" in window) { //is IE?
    alert('朋友，IE浏览器未适配哦~');
  }
  </script>
  <style type="text/css">
  .hljs-ln{border-collapse:collapse}.hljs-ln td{padding:0}.hljs-ln-n:before{content:attr(data-line-number)}
  </style>
  <style type="text/css">.site-top .lower nav{display:block !important;}.author-profile i,.post-like a,.post-share .show-share,.sub-text,.we-info a,span.sitename,.post-more i:hover,#pagination a:hover,.post-content a:hover,.float-content i:hover{color:#FE9600}.feature i,.download,.navigator i:hover,.links ul li:before,.ar-time i,span.ar-circle,.object,.comment .comment-reply-link,.siren-checkbox-radio:checked + .siren-checkbox-radioInput:after{background:#FE9600}::-webkit-scrollbar-thumb{background:#FE9600}.download,.navigator i:hover,.link-title,.links ul li:hover,#pagination a:hover,.comment-respond input[type='submit']:hover{border-color:#FE9600}.entry-content a:hover,.site-info a:hover,.comment h4 a,#comments-navi a.prev,#comments-navi a.next,.comment h4 a:hover,.site-top ul li a:hover,.entry-title a:hover,#archives-temp h3,span.page-numbers.current,.sorry li a:hover,.site-title a:hover,i.iconfont.js-toggle-search.iconsearch:hover,.comment-respond input[type='submit']:hover{color:#FE9600}.comments .comments-main{display:block !important;}.comments .comments-hidden{display:none !important;}background-position:center center;background-attachment:inherit;}
  </style>
</head>
</html>
<body class="page-template page-template-user page-template-page-analytics page-template-userpage-analytics-php page page-id-1297 chinese-font serif isWebKit">
  <div class="scrollbar" id="bar">
  </div>
  <a href="#" class="cd-top faa-float animated"></a>
  <section id="main-container">
    <div class="headertop filter-dot">
  <div id="banner_wave_1"></div>
  <div id="banner_wave_2"></div>
  <figure id="centerbg" class="centerbg">
    <div class="focusinfo no-select">
      <div class="header-tou">
        <a href="https://lichen312.gitee.io/blog/">
          <img src="https://gitee.com/lichen312/picbed/raw/master/image/20210124214938.png">
        </a>
      </div>
      <div class="header-info">
        <p>莫要三天打鱼,两天晒网!</p>
        <div class="top-social_v2">
          <li id="bg-pre">
            <img class="flipx" src="https://cdn.jsdelivr.net/gh/honjun/cdn@1.6/img/other/next-b.svg">
          </li>
          
          <li id="bg-next">
            <img src="https://cdn.jsdelivr.net/gh/honjun/cdn@1.6/img/other/next-b.svg">
          </li>
        </div>
      </div>
    </div>
  </figure>
  <div id="video-container" style="">
    <video style="object-fit: fill" id="bgvideo" class="video" video-name="" src="" width="auto" preload="auto">
    </video>
    <div id="video-btn" class="loadvideo videolive">
    </div>
    <div id="video-add">
    </div>
    <div class="video-stu">
    </div>
  </div>
  <div class="headertop-down faa-float animated" onclick="headertop_down()">
    <span>
      <i class="fa fa-chevron-down" aria-hidden="true">
      </i>
    </span>
  </div>
</div>
    <div id="page" class="site wrapper">
      <header class="site-header no-select gizle sabit" role="banner">
  <div class="site-top">
    <div class="site-branding">
      <span class="site-title">
        <span class="logolink moe-mashiro">
          <a href="/">
            <span class="sakurasono">LC</span>
            <span class="shironeko">site</span>
          </a>
        </span>
      </span>
    </div>
    <div class="searchbox search-form-submit">
      <i class="iconfont js-toggle-search iconsearch icon-search">
      </i>
    </div>
    <div id="show-nav" class="showNav mobile-fit">
      <div class="line line1">
      </div>
      <div class="line line2">
      </div>
      <div class="line line3">
      </div>
    </div>
    <div class="lower-cantiner">
      <div class="lower">
        <nav class="mobile-fit-control hide">
          <ul id="menu-new" class="menu">
            
              <li>
                <a href="/">
                  <span class="faa-parent animated-hover">
                    <i class="fa  fa-fort-awesome faa-shake" aria-hidden="true"></i>
                    首页
                  </span>
                </a>
                
              </li>
            
              <li>
                <a href="/archives">
                  <span class="faa-parent animated-hover">
                    <i class="fa  fa-archive faa-shake" aria-hidden="true"></i>
                    归档
                  </span>
                </a>
                
              </li>
            
              <li>
                <a href="javascript:;">
                  <span class="faa-parent animated-hover">
                    <i class="fa  fa-list-ul faa-vertical" aria-hidden="true"></i>
                    (๑•̀ㅂ•́)و✧
                  </span>
                </a>
                
              </li>
            
              <li>
                <a href="/comment/">
                  <span class="faa-parent animated-hover">
                    <i class="fa  fa-pencil-square-o faa-tada" aria-hidden="true"></i>
                    留言板
                  </span>
                </a>
                
              </li>
            
              <li>
                <a href="/donate/">
                  <span class="faa-parent animated-hover">
                    <i class="fa  fa-heart faa-pulse" aria-hidden="true"></i>
                    赞赏
                  </span>
                </a>
                
              </li>
            
              <li>
                <a href="javascript:;">
                  <span class="faa-parent animated-hover">
                    <i class="fa  fa-link faa-shake" aria-hidden="true"></i>
                    (ノへ￣、)
                  </span>
                </a>
                
              </li>
            
              <li>
                <a href="/">
                  <span class="faa-parent animated-hover">
                    <i class="fa  fa-leaf faa-wrench" aria-hidden="true"></i>
                    关于
                  </span>
                </a>
                
                  <ul class="sub-menu">
                    
                      <li>
                        <a href="/about/">
                          <i class="fa fa-meetup" aria-hidden="true"></i>
                          我？
                        </a>
                      </li>
                    
                      <li>
                        <a href="/theme-sakura/">
                          <i class="fa iconfont icon-sakura" aria-hidden="true"></i>
                          主题
                        </a>
                      </li>
                    
                  </ul>
                
              </li>
            
              <li>
                <a href="/atom.xml">
                  <span class="faa-parent animated-hover">
                    <i class="fa  fa-rss faa-pulse" aria-hidden="true"></i>
                    RSS
                  </span>
                </a>
                
              </li>
            
          </ul>
        </nav>
      </div>
    </div>
  </div>
</header>

      <link rel="stylesheet" type="text/css" href="/css/sharejs.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.css">
<div class="pattern-center-blank"></div>

  <div class="pattern-center single-center">
    <!-- 有配图默认渲染第一张 -->
    <div class="pattern-attachment-img lazyload" style="background-image: url(https://gitee.com/lichen312/picbed/raw/master/image/20220305165244.png);" src="https://cdn.jsdelivr.net/gh/honjun/cdn@1.6/img/loader/orange.progress-bar-stripe-loader.svg" data-src="https://gitee.com/lichen312/picbed/raw/master/image/20220305165244.png">
    </div>
    <header class="pattern-header single-header">
      <h1 class="entry-title">
      C++面向对象高级编程 -- 侯捷</h1>
      <p class="entry-census">
        <span>
          <a href="https://http://lichen312.gitee.io/">
            <img src="https://gitee.com/lichen312/picbed/raw/master/image/20210124214938.png">
          </a>
        </span>
        <span>
          <a href="https://http://lichen312.gitee.io/">LC</a>
        </span>
        <span class="bull">
        ·</span>
        2022-3-5<span class="bull">
        ·</span>
      <span id="busuanzi_value_page_pv"></span>次阅读</p>
      <!-- 开始添加字数统计-->
      
        
<div style="margin-top:10px;">
    <span class="post-time">
      <span class="post-meta-item-icon">
        <i class="fa fa-keyboard-o"></i>
        <span class="post-meta-item-text">  字数统计: </span>
        <!-- 安装插件npm install hexo-wordcount --save -->
        <span class="post-count">4.2k字</span>
      </span>
    </span>

    <span class="post-time">
      &nbsp; | &nbsp;
      <span class="post-meta-item-icon">
        <i class="fa fa-hourglass-half"></i>
        <span class="post-meta-item-text">  阅读时长: </span>
        <span class="post-count">16分</span>
      </span>
    </span>
</div>

      
      <!-- 添加完成 -->
      
    </header>
  </div>

<div id="content" class="site-content">
  <div id="primary" class="content-area">
    <main id="main" class="site-main" role="main">
      <article id="post-1" class="post-1 post type-post status-publish format-standard has-post-thumbnail hentry category-uncategorized">
        <div class="toc"></div>
        <!--<div class="toc-entry-content"><!-- 套嵌目录使用（主要为了支援评论）-->
        
        <div class="entry-content">
          <p>​    浙江大学Python基础课的笔记。</p>
<hr>
<h1 id="C-面向对象高级编程-–-侯捷"><a href="#C-面向对象高级编程-–-侯捷" class="headerlink" title="C++面向对象高级编程 – 侯捷"></a>C++面向对象高级编程 – 侯捷</h1><h2 id="class-类"><a href="#class-类" class="headerlink" title="class 类"></a>class 类</h2><ul>
<li><p>构造函数</p>
<pre><code class="c++">class A
{

public:
    A(x = 0; y = 0; z = 0) //参数可以有初始值
        : a(x), b(y), c(z) //初始列
    { }                    //函数体
    ~A()//析构函数，不带指针的一般不需要

private:
    int a;
    int b;
    int c;
};
</code></pre>
<p>如果类里面不含指针，那么拷贝构造和拷贝赋值默认的是把对象的成员变量赋值：</p>
<pre><code class="c++">A a(1,2,3)
//以下两种用法，b和c与a的成员变量相等。
A b(a);    //拷贝构造
A c = a; //拷贝赋值赋值
</code></pre>
<p>如果类里面含有指针，就不能用默认的拷贝和赋值，因为这样两个对象内的指针指向同一个东西，改变一个就全变了，这一般是我们不希望的，所以我们要自己写拷贝构造和赋值函数。其中拷贝赋值函数通过重载 = 运算符实现，如果类内申请了内存空间，要在析构函数中释放掉。</p>
<p>拷贝赋值函数中，一定要考虑自我赋值问题，举个例子：</p>
<pre><code class="C++">String&amp; String::operator = (const String&amp; str)
{
    if (this == &amp;str)
        return *this;
    ...
}
</code></pre>
<p>以上代码考虑了自我赋值，如果不考虑这点，后续通过指针delete掉new申请的空间后，因为是自我赋值，所以传进来的参数是自己，那么这个参数的指针内容也被delete掉了，程序会出错。</p>
</li>
<li><p>inline 函数</p>
<p>在类内定义的函数是inline函数（编译器决定最终是否会inline），inline函数类似c语言的宏定义，速度更快，但是会使代码体积膨胀，一般当函数内容简短的时候用inline。详细内容可见: <a href="http://c.biancheng.net/view/2201.html" target="_blank" rel="noopener">C++ inline内联函数详解</a></p>
</li>
<li><p>类成员函数体前加const，这个函数里面就不能改变成员变量的值。如果某个成员函数不改变成员变量，就都加const，否则可能出问题，例如：</p>
<pre><code class="c++">class A
{
    public:
    A(int a,int b)
    : x(a),y(b) {}
    int getx() {return x;}
    int gety() const {return y;}
    private: 
    int x;
    int y;
};
int main()
{
    const A a(1,2);
    a.getx(); //报错，因为getx不是const的函数，可能会改变a.x，而a是const的对象
}
</code></pre>
</li>
<li><p>类的临时对象</p>
<pre><code class="c++">typename() -&gt; 可以创建一个临时对象，到下一个语句生命周期就结束了。
Fraction f;
f = Fraction(1,2); //临时对象，f完成拷贝后，下个语句Fraction(1,2)生命周期结束
</code></pre>
</li>
<li><p>static 成员</p>
<p>static成员是类公用的，所以没有this指针，访问的时候用类名::成员来访问。因为static成员函数没有this指针，所以他不能访问非static类型的成员变量。一般我们在所有对象会公用成员的时候定义成static类型的，比如所有圆形都公用一个π值。</p>
</li>
</ul>
<h2 id="操作符重载"><a href="#操作符重载" class="headerlink" title="操作符重载"></a>操作符重载</h2><pre><code class="c++">operator 操作符 (...){...}
</code></pre>
<h2 id="new-和-delete-相关问题"><a href="#new-和-delete-相关问题" class="headerlink" title="new 和 delete 相关问题"></a>new 和 delete 相关问题</h2><p>new的时候，先申请内存空间，然后调用构造函数，delete的时候，先调用析构函数，然后再释放内存空间。</p>
<p>特别要注意，array new 一定要搭配 array delete，如果不搭配，array的空间也会删除，但是<strong>只调用一次析构函数!</strong>，这样会导致如果你的array里面是指针并且申请了内存空间，就内存泄漏了。</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220304210945210.png" alt="image-20220304210945210"></p>
<h2 id="namespace"><a href="#namespace" class="headerlink" title="namespace"></a>namespace</h2><p>设置namespace可以防止命名冲突，开发中一帮不用using namespace打开命名空间，这样不安全。</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220304211953403.png" alt="image-20220304211953403"></p>
<h2 id="类的复合，继承，委托"><a href="#类的复合，继承，委托" class="headerlink" title="类的复合，继承，委托"></a>类的复合，继承，委托</h2><ul>
<li><p>复合(Composition)</p>
<p>一个类的内部有其他的类，是类的复合。类复合，创建新的类的时候，先调用类内含有的其他类的构造函数，然后调用自身的构造函数，而类消失时，则是先调用自己的析构函数，然后才调用被包含的类的析构函数。注意调用的构造函数是默认构造函数，如果想要调用别的，要自己显式给出。</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220304213916668.png" alt="image-20220304213916668"></p>
</li>
<li><p>委托(Delegation)</p>
<p>类内含有其他类的指针，叫委托，和复合不同的是，本对象和指针指向的对象生命周期不同。</p>
</li>
<li><p>继承</p>
<p>派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问，则应在基类中声明为 private。</p>
<p>我们可以根据访问权限总结出不同的访问类型，如下所示：</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220304215350432.png" alt="image-20220304215350432"></p>
<p>派生类继承了基类的所有方法，除了一下几种：</p>
<ul>
<li><p>基类的构造函数、析构函数和拷贝构造函数</p>
</li>
<li><p>基类的重载运算符</p>
</li>
<li><p>基类的友元函数</p>
<p><img src="C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220304215806344.png" alt="image-20220304215806344"></p>
</li>
</ul>
</li>
</ul>
<pre><code> 构造函数和析构函数的调用和复合一样，基类的虚构函数必须是virtual的。
</code></pre><p>  <img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220304215003999.png" alt="image-20220304215003999"></p>
<h2 id="虚函数"><a href="#虚函数" class="headerlink" title="虚函数"></a>虚函数</h2><ul>
<li><p>non-virtual</p>
<p>不希望子类去重写这个方法</p>
</li>
<li><p>virtual</p>
<p>希望子类重新定义这个方法，而且自己也有默认定义</p>
</li>
<li><p>pure-virtual</p>
<p>希望子类一定要定义这个函数，自己不默认定义</p>
</li>
</ul>
<h2 id="conversion-function（转换函数）"><a href="#conversion-function（转换函数）" class="headerlink" title="conversion function（转换函数）"></a>conversion function（转换函数）</h2><p>两个方向，把当前对象转换成别的类型，把别的类型转换成当前对象。</p>
<ul>
<li><p>当前对象转出去</p>
<pre><code class="c++">class Fraction
{
public:
    Fraction(int num, int den = 1)
        : m_numerator(num), m_denominator(den) { }
    // 可以把当前类转换成double类型
    operator double() const
    {
        return m_numerator / m_denominator;
    }

private:
    int m_numerator; //分子
    int m_denominator; //分母
};

int main()
{
    Fraction f(3,5);
    double d = 1 + f; // d = 1 + 0.6 = 1.6 -&gt; 调用 operator double()将f转换成0.6
    std::cout &lt;&lt; d &lt;&lt; endl; // 输出1.6
}
</code></pre>
</li>
<li><p>别的类型转进来</p>
<pre><code class="c++">//重载一下+运算符
Fraction Fraction::operator+(const Fraction&amp; f){...}
int main()
{
    Fraction f(3,5);
    Fraction d = f + 1; // 结果是Fraction(8,5)
}
</code></pre>
<p>可以编译通过的原因是：1 + f 进行运算时，编译器发现Fraction有 + 的重载，但是重载的 + 运算符是Fraction + Fraction的，f满足而1不满足，所以编译器去找有没有把1转换成Fraction的方法，而Fraction的构造函数是one argument的，所以就通过构造函数将1转换成Fraction(1)，然后再和f相加。</p>
</li>
<li><p>explicit</p>
<p>在别的类型转进来的例子中，其实是运用了构造函数的<strong>隐式调用</strong>，以上两个例子同时存在的话，使用 Fraction d = f + 1 会产生二义性，导致编译不通过，这时候可以在构造函数前面加上explicit修饰，防止隐式调用。</p>
</li>
</ul>
<h2 id="pointer-like-classes-and-function-like-classes"><a href="#pointer-like-classes-and-function-like-classes" class="headerlink" title="pointer-like classes and function-like classes"></a>pointer-like classes and function-like classes</h2><p>pointer-like classes，指的是类就像指针一样，比较常见的例子是：</p>
<ul>
<li><p>智能指针</p>
<p>智能指针相关的内容可以参考这里：<a href="http://c.biancheng.net/view/7898.html#:~:text=C%2B%2B 智能指针底层是采用 引用计数 的方式实现的。,简单的理解，智能指针在申请堆内存空间的同时，会为其配备一个整形值（初始值为 1），每当有新对象使用此堆内存时，该整形值 %2B1；反之，每当使用此堆内存的对象被释放时，该整形值减 1。" target="_blank" rel="noopener">C++11 shared_ptr智能指针</a></p>
</li>
<li><p>STL迭代器</p>
<p>STL里面的各种数据结构都存在容器里面，可以用迭代器很方便的进行访问和遍历。迭代器是一个类，不是指针，但是用起来和使用指针一样，因为他里面重载了* , -&gt; 等运算符。 </p>
</li>
</ul>
<p>function-like classes，指的是类像函数一样，函数的调用是用()调用的，比如max(int a,int b)，如果类重载了()运算符，就可以像函数一样使用他，所以是像函数一样的类。</p>
<h2 id="模板-template"><a href="#模板-template" class="headerlink" title="模板 template"></a>模板 template</h2><p>泛型编程，避免代码重复</p>
<p>注意，模板类和函数的声明和定义要写在一起，不能分开写，也就是都写在.h文件中，否则<strong>编译不通过</strong>，具体原因可以参考:</p>
<p><a href="https://www.jianshu.com/p/dc94f0cbfcf7" target="_blank" rel="noopener">C++ 模板类的声明和定义都要放在 .h 文件中的原因 </a></p>
<ul>
<li><p>函数模板</p>
<pre><code class="c++">template &lt;class T&gt;
T max(const T&amp; a, const T&amp; b)
{
    return a &gt; b ? a : b;
}

int main()
{
    int a = 1,b = 2;
    double c = 1.3,d = 1,4;
    max(a,b); // 等于调用 max(int a, int b)
    max(c,d); // 等于调用 max(double a, double b)
}
</code></pre>
</li>
<li><p>类模板</p>
<pre><code class="c++">template &lt;class T&gt;
class A
{
public:
    A(T a, Tb)
        : x(a), y(b)
    { }
private:
    T x;
    T y;
}

int main()
{
    A&lt;double&gt; a1(1.3,1.4); //等于实例化了一个含有成员是double类型的x y的类
    A&lt;int&gt; a2(1,2); //等于实例化了一个含有成员是int类型的x y的类
}
</code></pre>
</li>
<li><p>成员模板</p>
<p>在类内成员函数定义成模板函数，具体可见下图：</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220305172917098.png" alt="image-20220305172917098"></p>
<p>再举一个例子，只能指针可以指向很多类型，但是如果现在指向了动物类，你可以用该指针指向狗吗？答案是可以的，因此要在智能指针中用成员模板来定义，来实现这个功能。</p>
</li>
<li><p>模板特化</p>
<p>在函数模板或者类模板中，有些时候编写的模板不是对所有类型通用的，例如在上面求最大值的模板函数中，对int或者double这种数据类型是可以正常使用的，但是如果模板类型T实例化的对象是字符串呢？显然我们所写的代码是不能进行我们想要的字符串比较的，所以我们要为字符串比较写一个特定的函数，即模板特化。</p>
<pre><code class="c++">template &lt;&gt;
int max&lt;const char*&gt;(const char* a, const char* b)
{
    //实现字符串比较的代码
}
</code></pre>
</li>
<li><p>模板偏特化</p>
<p>上面的模板特化例子是全特化，即模板的所有参数都特化了（上例只有一个参数），若有多个模板参数，你特化其中的某些个，就是模板的偏特化。</p>
<pre><code class="c++">// 类模板偏特化demo
template &lt;typename T, typename Allocator_T&gt;
class MyVector {
public:
    MyVector()
    {
        std::cout &lt;&lt; &quot;Normal version.&quot; &lt;&lt; std::endl;
    }
};

template &lt;typename T&gt;
class MyVector&lt;T, DefaultAllocator&gt;
{
public:
    MyVector() {
        std::cout &lt;&lt; &quot;Partial version.&quot; &lt;&lt; std::endl;
    }
};

MyVector&lt;int, MyAnotherAllocator&gt; v1;
MyVector&lt;int, DefaultAllocator&gt; v2;
</code></pre>
<p>输出结果</p>
<pre><code class="c+=">Normal version.
Partial version.
</code></pre>
<p>以上是数量上的模板偏特化，还可以在范围上对模板进行偏特化（函数一般不使用模板偏特化，因为可能和函数重载冲突），比如：</p>
<pre><code class="c++">template &lt;class T&gt;
class A
{
public:
    A()
    {
        cout &lt;&lt; &quot;T&quot; &lt;&lt; endl;
    }
};

template &lt;class T&gt;
class A&lt;T*&gt;
{
public:
    A()
    {
        cout &lt;&lt; &quot;T*&quot; &lt;&lt; endl;
    }
};

A&lt;int&gt; a;
A&lt;int*&gt; b;
</code></pre>
<p>输出</p>
<pre><code class="c++">T
T*
</code></pre>
</li>
<li><p>模板的模板参数</p>
<p>有些类模板的参数需要也是一个模板来更方便使用，比如以下例子：</p>
<pre><code class="c++">Stack&lt;int, std::vector&lt;int&gt;&gt; vStack;
</code></pre>
<p>这里不仅要指定stack中存储的数据类型，因为这里stack的容器用vector实现，所有还要指定vector的参数类型，所以可以在模板中声明类模板，更方便使用。</p>
<pre><code class="c++">template &lt;typename T, 
    template &lt;typename Elem,typename allocator&lt;e&gt;&gt; class Count = std::deque&gt;
class Stack
{
private: 
    Cont&lt;T&gt; elems;
    ...
};
</code></pre>
</li>
</ul>
<h2 id="c-11-的一些好用的新特性"><a href="#c-11-的一些好用的新特性" class="headerlink" title="c++ 11 的一些好用的新特性"></a>c++ 11 的一些好用的新特性</h2><p>这里侯捷老师主要讲了三个好用的新特性，但是没有仔细展开，这个会在后续的c++ 11的专门课程里实习。</p>
<ul>
<li><p>可变参数模板</p>
<p>模板是一个数量可变的参数，看下面这个例子：</p>
<pre><code class="c++">void print()
{

}
template&lt;class T,class... args&gt;
void print(const T&amp; first,const args&amp;... arg)
{
    cout &lt;&lt; first &lt;&lt; endl;
    print(arg...);
}

int main()
{
    print(1,&quot;hellow&quot;,3);
}
输出：
1
hellow
2
</code></pre>
</li>
<li><p>auto</p>
<p>auto定义的变量，后通过后面的复制内容，帮助我们自己决定变量的类型而不用我们自己给出来，很方便</p>
<pre><code class="c++">int main()
{
    vector&lt;int&gt; v = {1,2,3};
    auto it = v.begin();
    cout &lt;&lt; *it &lt;&lt; endl;
}
输出：
1
</code></pre>
</li>
<li><p>新循环</p>
<p>用：遍历容器，java和python一样：</p>
<pre><code class="c++">int main()
{
    vector&lt;int&gt; v = {1,2,3,4,5,7,8};
    for(auto i : v) //可以引用改变值，auto&amp; i : v 即可
    {
        cout &lt;&lt; i &lt;&lt; &quot; &quot;;
    }
}
输出:
1 2 3 4 5  7 8
</code></pre>
</li>
</ul>
<h2 id="reference-引用"><a href="#reference-引用" class="headerlink" title="reference 引用"></a>reference 引用</h2><p>给函数传参数的时候最好传引用，传引用的效果和传指针一样，但是还是和操作变量一样操作就可以了。当传过去的参数是一个类，然后这个类结构比较大的时候，这种做法能够很好的提高效率。</p>
<p>但是传引用代表了函数里面能改变我们传过去的参数，如果不想被改变，可以加const修饰。</p>
<p>返回值也最好传引用，但是如果返回的东西是函数体能创造出来的话，则不能传引用，因为函数结束后里面的变量的生命周期就结束了。</p>
<p>引用变量代表了被他引用的变量，所以他们的值和地址都相同，并且sizeof也相同，但是这是假象，其实引用变量底层也是指针实现的：</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220305172058931.png" alt="image-20220305172058931"></p>
<p>引用一般用在参数传递上面，因为速度等同于传指针，但是使用的形式和传普通参数一样，所以很方便。但是要注意函数不能同时出现传值和传引用，这样编译器无法区分，比如：</p>
<pre><code class="c++">void print(int x);
void print(int&amp; x); // 无法区分
</code></pre>
<h2 id="Object-Model-对象模型"><a href="#Object-Model-对象模型" class="headerlink" title="Object Model 对象模型"></a>Object Model 对象模型</h2><p>一个类在继承另一个类的时候，除了继承数据外，还要继承函数的调用权，如果函数是普通函数，则静态绑定，用call xxx来通过地址调用，如果是虚函数，则在内存空间中第一个是虚指针，指向该对象的虚表，表内是虚函数的地址，通过这种方式动态绑定虚函数，实现多态，例如有以下三个类：</p>
<pre><code class="c++">class A
{
public:
    virtual void vfunc1();
    virtual void vfunc2();
    void func1();
    void func2();
private:
    int m_data1,m_data2;
};

class B : public A
{
public:
    virtual void vfunc1();
    void func2();
private:
    int m_data3;
};

class c : public B
{
public:
    virtual void vfunc1();
    void func2();
private:
    int m_data1,m_data4;
};
</code></pre>
<p>其对应的对象模型如下图所示：</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220305153013537.png" alt="image-20220305153013537"></p>
<p>那么为什么要使用这种方式？假如你设计了一个shape类，将来有例如圆形，矩形等形状要继承shape这个类，而他们都有同样一个功能draw()，去把这个形状画出来，那不同形状的draw()就不同，使用虚函数，可以在父类声明draw这个虚函数，让子类自己去实现。你现在创建一个List，这个List你可以放圆形，矩形，所以你创建类型为List<shape>，这时候你遍历它然后调用draw的时候，就可以对每个对象使用虚指针和虚标找到每个对象自己的draw()函数了，这样可以很方便的实现多态。</shape></p>
<p>关于动态绑定和静态绑定还有以下一个例子：</p>
<pre><code class="C++">class A
{
public:
    virtual void f()
    {
        cout &lt;&lt; &#39;A&#39; &lt;&lt; &#39; &#39;;
    }
};

class B : public A
{
public:
    void f()
    {
        cout &lt;&lt; &#39;B&#39; &lt;&lt; &#39; &#39;;
    }
};

int main()
{
    B b;
    A a = (A)b; // 把B强制转换成A赋值给A，A还是A，只不过成员变量会被B替代，但是指向的函数还是自己的
    a.f();
    A* p = &amp;b; // 取得了B的地址，所以访问时虚指针指向了B的虚表，调用了B的函数
    p-&gt;f();
}
输出：A B
</code></pre>
<h2 id="this指针"><a href="#this指针" class="headerlink" title="this指针"></a>this指针</h2><p>所有类的成员函数都有一个隐含的参数，指向调用本函数的对象的指针this，这也是实现多态的关键。实际上调用object.func()，使用的是this-&gt;func()。</p>
<p>在下图的例子中，myDoc调用OnFileOpen()函数，其实是把指向myDoc这个对象的指针传给了OnFileOpen()隐含的this参数。所以在Serialize()函数中，this所指向的也是myDoc，因此通过this找到了myDoc的内存空间，通过这里的虚指针找到虚表来找到Serialize()的地址，因为this所指向的是myDoc，myDoc是CMyDoc类，所以这时候调用的是CMyDoc类的Serialize()函数而不是他的父类的函数，实现了多态。</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220305154924213.png" alt="image-20220305154924213"></p>
<h2 id="const"><a href="#const" class="headerlink" title="const"></a>const</h2><ul>
<li><p>const指针变量</p>
<pre><code class="c++">int p;
const int* p1 = &amp;p;//p1可变，*p1不可变，此时不能用*p1来修改，但是p1可以转向
int* const p2 = &amp;p;//p2不可变，*p2可变，此时允许*p2来修改其值，但是p2不能转向。
const int* const p3 = &amp;me;//p3不可变，*p3也不可变，此时既不能用*p3来修改其值，也不能转向
</code></pre>
<p>const指针可以接受const和非const地址，但是非const指针只能接受非const地址。所以const指针的能力更强一些，所以尽量多用const指针，这是一种习惯。</p>
</li>
<li><p>函数const参数</p>
<pre><code class="c+=">int max(const int&amp; a, const int&amp; b) // 传递进来的变量a,b在函数内部不能被改变
</code></pre>
</li>
<li><p>类成员函数函数体前加const</p>
<pre><code class="c++">class A
{
public:
    void f() const {...} //意思是该函数不会改变类A的成员变量
    ...
}
</code></pre>
</li>
</ul>
<p>如果某个函数不需要改变传递的参数的值，或者成员函数不改变成员变量，就加上const，否则无法接受const类型的变量或者对象，因为你可能改变他，通不过编译：</p>
<p><img src="https://gitee.com/lichen312/picbed/raw/master/image/image-20220305163010426.png" alt="image-20220305163010426"></p>

        </div>
        <!-- .entry-content -->
        <div class="single-reward">
          <div class="reward-open">赏
            <div class="reward-main">
              <ul class="reward-row">
                <li class="alipay-code"><img src="https://gitee.com/lichen312/picbed/raw/master/image/aly_get.png"></li>
                <li class="wechat-code"><img src="https://gitee.com/lichen312/picbed/raw/master/image/wechat_get.png"></li>
              </ul>
            </div>
          </div>
        </div>
        <div style="text-align:center; width: 100%" class="social-share share-mobile" data-disabled="diandian, tencent"></div>
        <footer class="post-footer">
          <div class="post-lincenses"><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank" rel="nofollow"><i class="fa fa-creative-commons" aria-hidden="true"></i> 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议</a></div>
          <div class="post-tags">
          </div>
          <div class="post-share">
            <div class="social-share sharehidden share-component"></div>
            <i class="iconfont show-share icon-forward"></i>
          </div>
        </footer><!-- .entry-footer -->
      </article>
      <!-- #post-## -->
      <div class="toc" style="background: none;"></div>
      <section class="post-squares nextprev">
        
        
          
            <div class="post-nepre full next">
          
            <a href="/2021/11/11/TCL语言基础/" rel="next">
              <div class="background">
                <img class="lazyload" src="https://cdn.jsdelivr.net/gh/honjun/cdn@1.6/img/loader/orange.progress-bar-stripe-loader.svg" data-src="https://gitee.com/lichen312/picbed/raw/master/image/TCL.png" style="width: 100%; height: 100%; object-fit: cover; pointer-events: none;" onerror="imgError(this,3)" src="https://gitee.com/lichen312/picbed/raw/master/image/TCL.png">
              </div>
              <span class="label">
              Next Post</span>
              <div class="info">
                <h3>
                TCL脚本语言基础</h3>
                <hr>
              </div>
            </a>
          </div>
        
      </section>
      
      <section class="author-profile">
        <div class="info" itemprop="author" itemscope="" itemtype="https://schema.org/Person">
          <a href="https://http://lichen312.gitee.io/" class="profile gravatar"><img src="https://gitee.com/lichen312/picbed/raw/master/image/20210124214938.png" itemprop="image" alt="LC" height="70" width="70"></a>
          <div class="meta">
            <span class="title">Author</span>
            <h3 itemprop="name">
            <a href="https://http://lichen312.gitee.io/" itemprop="url" rel="author">LC</a>
            </h3>
          </div>
        </div>
        <hr>
        <p><i class="iconfont icon-write"></i>菜鸡罢了</p>
      </section>
    </main><!-- #main -->
  </div><!-- #primary -->
</div>



    </div>    
    <div class="ins-search">
    <div class="ins-search-mask"></div>
    <div class="ins-search-container">
        <div class="ins-input-wrapper">
            <input type="text" class="ins-search-input" placeholder="请输入关键词..."/>
            <span class="ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: '文章',
            // PAGES: '页面',
            CATEGORIES: '分类',
            TAGS: '标签',
        },
        ROOT_URL: '/',
        CONTENT_URL: '/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>
    <!-- <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2022 lichen<br>
      powered_by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer> -->
<footer id="colophon" class="site-footer" role="contentinfo">
  <div class="site-info">
    <div class="footertext">
      <div class="img-preload">
        <img src="https://cdn.jsdelivr.net/gh/honjun/cdn@1.6/img/other/wordpress-rotating-ball-o.svg">
        <img src="https://cdn.jsdelivr.net/gh/honjun/cdn@1.6/img/other/disqus-preloader.svg">
      </div>
      <p style="color: #666666;">&copy 2018</p>
    </div>
    <div class="footer-device">
    <p style="font-family: 'Ubuntu', sans-serif;">
        <span style="color: #b9b9b9;">Theme <a href="https://github.com/honjun/hexo-theme-sakura" target="_blank" style="color: #b9b9b9;;text-decoration: underline dotted rgba(0, 0, 0, .1);">Sakura</a> <i class="iconfont icon-sakura rotating" style="color: #ffc0cb;display:inline-block"></i> by <a href="https://2heng.xin/" target="_blank" style="color: #b9b9b9;;text-decoration: underline dotted rgba(0, 0, 0, .1);">Mashiro</a>&<a href="https://www.hojun.cn/" target="_blank" style="color: #b9b9b9;;text-decoration: underline dotted rgba(0, 0, 0, .1);">Hojun</a>, Powered by Hexo, Hosted by Coding Pages</a>
        </span>
      </p>
    </div>
  </div><!-- .site-info -->
</footer>



<!-- <script src="/js/tocbot.js"></script> -->
<script type="text/javascript" src="/js/lib.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script type="text/javascript" src="/js/InsightSearch.js"></script>
<script type="text/javascript" src="/js/jquery.fancybox.min.js"></script>
<script type="text/javascript" src="/js/zoom.min.js"></script>
<script type="text/javascript" src="/js/sakura-app.js"></script>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src='//unpkg.com/valine@1.3.4/dist/Valine.min.js'></script>
<script src="/js/botui.js"></script>
<!-- 不蒜子 网页计数器 -->
<script src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.4.2/tocbot.min.js"></script> -->
<script type="text/javascript">
/* <![CDATA[ */
if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {
  var Poi = {"pjax":"1","movies":{"url": "https://cdn.jsdelivr.net/gh/honjun/hojun@1.2","name":"Unbroken.mp4","live":"close"},"windowheight":"fixed","codelamp":"close","ajaxurl":"","order":"asc","formpostion":"bottom"};
} else {
  var Poi = {"pjax":"1","movies":{"url": "https://cdn.jsdelivr.net/gh/honjun/hojun@1.2","name":"Unbroken.mp4","live":"open"},"windowheight":"auto","codelamp":"close","ajaxurl":"","order":"asc","formpostion":"bottom"};
}
/* ]]> */

</script>
<script>
$(document).ready(function() {
  if ($(".toc").length > 0 && document.body.clientWidth > 1200) {
    if ($(".pattern-center").length > 0) { //有图的情况
      tocbot.init({
          // Where to render the table of contents.
          tocSelector: '.toc', // 放置目录的容器
          // Where to grab the headings to build the table of contents.
          contentSelector: '.entry-content', // 正文内容所在
          // Which headings to grab inside of the contentSelector element.
          scrollSmooth: true,
          headingSelector: 'h1, h2, h3, h4, h5', // 需要索引的标题级别
          headingsOffset: -400,
          scrollSmoothOffset: -85
      });
    } else {
      tocbot.init({
          // Where to render the table of contents.
          tocSelector: '.toc', // 放置目录的容器
          // Where to grab the headings to build the table of contents.
          contentSelector: '.entry-content', // 正文内容所在
          // Which headings to grab inside of the contentSelector element.
          scrollSmooth: true,
          headingSelector: 'h1, h2, h3, h4, h5', // 需要索引的标题级别
          headingsOffset: -85,
          scrollSmoothOffset: -85
      });
    }
    var offsetTop = $('.toc').offset().top - 95;
    window.onscroll = function() {
      var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
      if (scrollTop >= offsetTop) {
        $('.toc').addClass('toc-fixed');
      } else {
        $('.toc').removeClass('toc-fixed');
      }
    }
  }
});
</script>

    <div class="openNav no-select" style="height: 50px;">
      <div class="iconflat no-select" style="width: 50px; height: 50px;">
        <div class="icon"></div>
      </div>
      <div class="site-branding search-form-submit">
        <i class="iconfont js-toggle-search iconsearch icon-search"></i>
      </div>
    </div>
  </section>
  <div id="mo-nav" class="">
  <div class="m-avatar">
    <img src="https://gitee.com/lichen312/picbed/raw/master/image/20210124214938.png">
  </div>
  <p style="text-align: center; color: #333; font-weight: 900; font-family: 'Ubuntu', sans-serif; letter-spacing: 1.5px">LCsite</p>
  <p style="text-align: center; word-spacing: 20px;">
    
      
        <a href="http://github.com/honjun" class="fa fa-github" target="_blank" style="color: #333; margin-left:20px"></a>
      
        <a href="http://weibo.com/mashirozx?is_all=1" class="fa fa-weibo" target="_blank" style="color: #dd4b39; margin-left:20px"></a>
      
        <a href="https://wpa.qq.com/msgrd?v=3&uin=954655431&site=qq&menu=yes" class="fa fa-qq" target="_blank" style="color: #25c6fe; margin-left:20px"></a>
      
    
  </p>
  <ul id="menu-new-1" class="menu">
    
      <li>
        <a href="/">
          <span class="faa-parent animated-hover">
            <i class="fa  fa-fort-awesome faa-shake" aria-hidden="true"></i>
            首页
          </span>
        </a>
        
      </li>
    
      <li>
        <a href="/archives">
          <span class="faa-parent animated-hover">
            <i class="fa  fa-archive faa-shake" aria-hidden="true"></i>
            归档
          </span>
        </a>
        
      </li>
    
      <li>
        <a href="javascript:;">
          <span class="faa-parent animated-hover">
            <i class="fa  fa-list-ul faa-vertical" aria-hidden="true"></i>
            (๑•̀ㅂ•́)و✧
          </span>
        </a>
        
      </li>
    
      <li>
        <a href="/comment/">
          <span class="faa-parent animated-hover">
            <i class="fa  fa-pencil-square-o faa-tada" aria-hidden="true"></i>
            留言板
          </span>
        </a>
        
      </li>
    
      <li>
        <a href="/donate/">
          <span class="faa-parent animated-hover">
            <i class="fa  fa-heart faa-pulse" aria-hidden="true"></i>
            赞赏
          </span>
        </a>
        
      </li>
    
      <li>
        <a href="javascript:;">
          <span class="faa-parent animated-hover">
            <i class="fa  fa-link faa-shake" aria-hidden="true"></i>
            (ノへ￣、)
          </span>
        </a>
        
      </li>
    
      <li>
        <a href="/">
          <span class="faa-parent animated-hover">
            <i class="fa  fa-leaf faa-wrench" aria-hidden="true"></i>
            关于
          </span>
        </a>
        
          <ul class="sub-menu">
            
              <li>
                <a href="/about/">
                  <i class="fa fa-meetup" aria-hidden="true"></i>
                  我？
                </a>
              </li>
            
              <li>
                <a href="/theme-sakura/">
                  <i class="fa iconfont icon-sakura" aria-hidden="true"></i>
                  主题
                </a>
              </li>
            
          </ul>
        
      </li>
    
      <li>
        <a href="/atom.xml">
          <span class="faa-parent animated-hover">
            <i class="fa  fa-rss faa-pulse" aria-hidden="true"></i>
            RSS
          </span>
        </a>
        
      </li>
    
  </ul>
  <p style="text-align: center; font-size: 13px; color: #b9b9b9;">&copy 2019 hexo-sakura</p>
</div>
<button onclick="topFunction()" class="mobile-cd-top" id="moblieGoTop" title="Go to top" style="display: none;"><i class="fa fa-chevron-up" aria-hidden="true"></i></button>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">
<script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<!-- require MetingJS -->
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>
<style>
  .aplayer .aplayer-lrc {
    height: 35px;
  }
  .aplayer .aplayer-lrc p{
    font-size: 16px;
    font-weight: 700;
    line-height: 18px !important;
  }
  .aplayer .aplayer-lrc p.aplayer-lrc-current{
    color: #FF1493;
  }
  .aplayer.aplayer-narrow .aplayer-body{
    left: -66px !important;
  }
  .aplayer.aplayer-fixed .aplayer-lrc {
    display: none;
  }
  .aplayer .aplayer-lrc.aplayer-lrc-hide {
      display:none !important;
  }
  .aplayer.aplayer-fixed .lrc-show {
    display: block;
    background: rgba(255, 255, 255, 0.8);
  }
</style>
<meting-js

    id="2660651585"

    server="netease"

    type="playlist"

    fixed="true"

    autoplay="false"

    loop="all"

    order="random"

    preload="auto"

    volume="0.7"

    mutex="true"

</meting-js>
<script>
  $(function(){
    $('body').on('click', '.aplayer', function(){
      if($('.aplayer-button').hasClass('aplayer-play')) {
        $('.aplayer-lrc').removeClass('lrc-show');
      } else {
        $('.aplayer-lrc').addClass('lrc-show');
      }
    })
  });
</script>
</body>
</html>